package com.bfly.mall.system.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bfly.common.ResponseUtil;
import com.bfly.common.json.JsonUtil;
import com.bfly.common.util.DataConvertUtils;
import com.bfly.common.util.FileUtil;
import com.bfly.common.util.StringUtil;
import com.bfly.core.base.controller.BaseController;
import com.bfly.core.base.entity.ResponseData;
import com.bfly.core.cache.CityCacheUtil;
import com.bfly.core.config.ResourceConfigure;
import com.bfly.core.context.CacheableThreadLocal;
import com.bfly.core.context.event.CityReloadEvent;
import com.bfly.core.security.ActionModel;
import com.bfly.mall.system.entity.City;
import com.bfly.mall.system.service.ICityService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.TaskExecutor;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.zeroturnaround.zip.ZipUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 城市Controller
 *
 * @author 长沙商脉科技有限公司
 * @date 2020/10/10 17:52
 */
@RestController
@RequestMapping(value = "/manage/city")
public class CityController extends BaseController {

    @Autowired
    private ICityService cityService;
    @Autowired
    @Qualifier("taskExecutor")
    private TaskExecutor taskExecutor;

    /**
     * 全国省份列表
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/10/10 17:55
     */
    @GetMapping(value = "/list")
    public void listCity(HttpServletRequest request, HttpServletResponse response) {
        String levelStr = request.getParameter("level");
        String parentIdStr = request.getParameter("parentId");
        Map<String, Object> param = new HashMap<>(1);
        if (StringUtils.isNotBlank(levelStr)) {
            int level = DataConvertUtils.convertToInteger(levelStr);
            param.put("level", level);
        }
        if (StringUtils.isNotBlank(parentIdStr)) {
            int parentId = DataConvertUtils.convertToInteger(parentIdStr);
            param.put("parent_id", parentId);
        }
        Map<String, Boolean> sortMap = new HashMap<>(1);
        sortMap.put("id", true);
        CacheableThreadLocal.set(false);
        List<City> list = cityService.getList(param, null, sortMap);
        JSONArray array = new JSONArray();
        if (list != null) {
            list.forEach(city -> {
                boolean hasChildren = CollectionUtils.isNotEmpty(city.getChildren());
                if (hasChildren) {
                    city.setChildren(null);
                }
                JSONObject json = JsonUtil.toJsonFilter(city);
                json.put("hasChildren", hasChildren);
                array.add(json);
            });
        }
        ResponseUtil.writeJson(response, ResponseData.getSuccess(array));
    }

    /**
     * 新增城市
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/10/10 17:56
     */
    @PostMapping(value = "/add")
    @ActionModel(value = "新增城市")
    public void addCity(@RequestBody @Valid City city, BindingResult result, HttpServletResponse response) {
        validData(result);
        cityService.save(city);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 修改城市
     *
     * @author 长沙商脉科技有限公司
     * @date 2018/12/14 11:33
     */
    @PostMapping(value = "/edit")
    @ActionModel(value = "修改城市")
    public void editCity(@RequestBody @Valid City city, BindingResult result, HttpServletResponse response) {
        validData(result);
        cityService.edit(city);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 删除城市
     *
     * @author 长沙商脉科技有限公司
     * @date 2018/12/14 11:37
     */
    @PostMapping(value = "/delete")
    @ActionModel(value = "删除城市")
    public void removeCity(HttpServletResponse response, @RequestBody Integer... dirId) {
        cityService.remove(dirId);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 刷新缓存
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/12/5 22:59
     */
    @GetMapping(value = "/refresh/cache")
    @ActionModel(value = "刷新城市缓存")
    public void reloadCity(HttpServletResponse response, HttpServletRequest request) {
        WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
        taskExecutor.execute(() -> context.publishEvent(new CityReloadEvent(context)));
        ResponseUtil.writeJson(response, ResponseData.getSuccess(""));
    }

    /**
     * 下载城市JSON文件
     *
     * @author 长沙商脉科技有限公司
     * @date 2020/12/23 15:50
     */
    @GetMapping(value = "/download")
    @ActionModel(value = "下载城市JSON文件")
    public void download(HttpServletResponse response) {
        List<City> district = CityCacheUtil.getDistrict();
        List<City> cities = CityCacheUtil.getCity();
        List<City> province = CityCacheUtil.getProvince();

        String districtJson = JsonUtil.toJsonFilterForArray(district).toJSONString();
        String cityJson = JsonUtil.toJsonFilterForArray(cities).toJSONString();
        String provinceJson = JsonUtil.toJsonFilterForArray(province).toJSONString();

        String districtFile = ResourceConfigure.getConfig().getTempRootPath() + File.separator + "district.json";
        String cityFile = ResourceConfigure.getConfig().getTempRootPath() + File.separator + "city.json";
        String provinceFile = ResourceConfigure.getConfig().getTempRootPath() + File.separator + "province.json";

        String fileName= StringUtil.getRandomString(32).toLowerCase()+".zip";
        String zipFile = ResourceConfigure.getConfig().getTempRootPath() + File.separator + fileName;

        ByteArrayInputStream districtInputStream = new ByteArrayInputStream(districtJson.getBytes());
        FileUtil.writeFile(districtInputStream, districtFile);

        ByteArrayInputStream cityInputStream = new ByteArrayInputStream(cityJson.getBytes());
        FileUtil.writeFile(cityInputStream, cityFile);

        ByteArrayInputStream provinceInputStream = new ByteArrayInputStream(provinceJson.getBytes());
        FileUtil.writeFile(provinceInputStream, provinceFile);

        File[] files = new File[]{new File(districtFile), new File(cityFile), new File(provinceFile)};
        ZipUtil.packEntries(files, new File(zipFile));
        String url = ResourceConfigure.getResourceHttpUrl("/temp/"+fileName);
        ResponseUtil.writeJson(response, ResponseData.getSuccess(url));
    }
}
